--RemoteUI.lua
require 'fairygui.Window'

local tinsert = table.insert
local tsort   = table.sort
local tunpack = table.unpack
local sfind   = string.find
local ssub    = string.sub

RemoteUI = class(Window)
local prop = property(RemoteUI)
prop:accessor("user_list", {})
prop:accessor("user_map", {})
prop:accessor("list_view", nil)
prop:accessor("control_custom", nil)
prop:accessor("inputAddress", nil)
prop:accessor("btn_computer", nil)
prop:accessor("inputSearch", nil)
prop:accessor("btn_search", nil)

function RemoteUI:__init()
    self:loadLayout("RemoteUI", "Main")
end

function RemoteUI:split(str, token)
    local pos, t = 0, {}
    if #str > 0 then
        for st, sp in function() return sfind(str, token, pos, true) end do
            if st > 1 then
                t[#t + 1] = ssub(str, pos, st - 1)
            end
            pos = sp + 1
        end
        if pos <= #str then
            t[#t + 1] = ssub(str, pos)
        end
    end
    return t
end

function RemoteUI:addr(value)
    local ip, port = tunpack(self:split(value, ":"))
    return ip, tonumber(port)
end


function RemoteUI:login(host, port)
    g_world_mgr:loginRemote(host, port, function(err)
        if err then
            print("[RemoteUI][login] err:"..err)
            return
        end
        print("[LOGIN_LOG][RemoteUI][loadRemoteWorlds] host:"..host)
        g_world_mgr:loadRemoteWorlds(function(err1)
            if err1 then
                print("[RemoteUI][login] loadRemoteWorlds err:"..err1)
                return
            end
            local panel = self:openGUI("BrowseUI", true)
            panel:initRemoteUI(nil)
        end)
    end)
end

-- 初始化(仅执行一次)
function RemoteUI:initEvent()
    self.list_view = self:getChild("listView")
    -- 下拉刷新
    self.list_view.scrollPane.onPullDownRelease:Add(function()
        local header = self.list_view.scrollPane.header;
        if header:GetController("c1").selectedIndex == 1 then
            header:GetController("c1").selectedIndex = 2;
            self.list_view.scrollPane:LockHeader(header.sourceHeight);
            self:loadComputer(function(err)
                g_time_mgr:add(1, 1, function()
                    if err then
                        g_event_mgr:notifyListener("onWarnTip", err)
                        header:GetController("c1").selectedIndex = 0;
                        self.list_view.scrollPane:LockHeader(0);
                        return
                    end
                    header:GetController("c1").selectedIndex = 3;
                    self.list_view.scrollPane:LockHeader(35);
                    g_time_mgr:add(2, 1, function()
                        header:GetController("c1").selectedIndex = 0;
                        self.list_view.scrollPane:LockHeader(0);
                    end)
                end)
            end)
        end
    end)
    self.list_view.scrollPane.header.onSizeChanged:Add(function()
        local selectedIndex = self.list_view.scrollPane.header:GetController("c1").selectedIndex;
        if selectedIndex == 2 or selectedIndex == 3 then
            return;
        end

        local c1 = self.list_view.scrollPane.header:GetController("c1");
        if self.list_view.scrollPane.header.height > self.list_view.scrollPane.header.sourceHeight then
            c1.selectedIndex = 1;
        else
            c1.selectedIndex = 0;
        end
    end);

    self.control_custom = self:getController("custom")
    self.inputAddress = self:getChild("inputAddress")
    self.inputSearch = self:getChild("inputSearch")
    self.btn_computer = self:getChild("computer")
    self.btn_search = self:getChild("search")
    self:getChild("close").onClick:Add(function()
        self:close()
    end)
    self.btn_computer.onClick:Add(function()
        if self.control_custom.selectedPage == "default" then
            self.control_custom:SetSelectedPage("custom")
            self.inputAddress:RequestFocus()
        else
            self.inputSearch.text = ""
            self:upListView()
            self.control_custom:SetSelectedPage("default")
        end
    end)
    self.btn_search.onClick:Add(function()
        if self.control_custom.selectedPage == "default" then
            self.control_custom:SetSelectedPage("search")
            self.inputSearch:RequestFocus()
        else
            self.inputSearch.text = ""
            self:upListView()
            self.control_custom:SetSelectedPage("default")
        end
    end)
    self:getChild("login").onClick:Add(function()
        local address = self.inputAddress.text
        if #address == 0 then
            return
        end
        local host, port = self:addr(address)
        self:login(host, port)
    end)
    self.inputSearch.onChanged:Add(function()
        self:upListView()
    end)
end

function RemoteUI:resetUser()
    self.user_map = {}
end

function RemoteUI:loadComputer(callback)
    self:resetUser()
    g_lan_mgr:boardcast("online", {}, function(err, data)
        -- 广播结束
        if err == "done" then
            self:upListView()
            if callback then
                callback()
            end
            return
        end
        if err then
            print("[LRemoteUIanMgr][loadComputer] online err="..err)
            if callback then
                callback(err)
            end
            return
        end
        print("online data:"..type(data).." "..json.encode(data))
        local host = data.host
        if not self.user_map[host] then
            self.user_map[host] = {}
        end
        local user = data.user
        self.user_map[host].user = user
        self.user_map[host].time = os.time()
        self.user_map[host].status = 1
        self:upListView()
    end, 5)
end

-- 打开UI执行一次
function RemoteUI:initComponent()
    self.inputAddress.text = ""
    self.inputSearch.text = ""
    self.control_custom:SetSelectedPage("default")
    self:loadComputer()
end

function RemoteUI:upListView()
    self.list_view:RemoveChildren(0, -1, true)
    self.user_list = {}
    for host,item in pairs(self.user_map) do
        -- 搜索过滤
        if self.inputSearch.text ~= "" then
            if not string.find(item.user, self.inputSearch.text) and not string.find(host, self.inputSearch.text) then
                goto continue
            end
        end
        tinsert(self.user_list, {
            host=host,
            user=item.user,
            time=item.time,
            status = item.status
        })
        :: continue ::
    end
    tsort(self.user_list, function(a, b)
        return string.upper(a.user:sub(1, 1)) < string.upper(b.user:sub(1, 1))
    end)
    for i,item in ipairs(self.user_list) do
        local child_node = UIPackage.CreateObject("Main", "list_item")
        child_node:GetChild("txt_name").text = item.user
        child_node:GetChild("txt_address").text = item.host
        local cStatus = child_node:GetController("status")
        cStatus.selectedIndex = item.status
        child_node:GetChild("btn_open").onClick:Add(function()
            self:login(item.host)
        end)
        child_node:GetChild("btn_open").enabled = (item.status == 1)
        self.list_view:AddChild(child_node)
    end
end

function RemoteUI:onClose()
end